global bandas_asm

section .rodata
if1: dd 96,96,96,96
if2: dd 288,288,288,288
if3: dd 480,480,480,480
if4: dd 672,672,672,672 
alpha: db 0,0,0,0xFF,0,0,0,0xFF,0,0,0,0xFF,0,0,0,0xFF
c1: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
c2: db 64,64,64,0,64,64,64,0,64,64,64,0,64,64,64,0
c3: db 128,128,128,0,128,128,128,0,128,128,128,0,128,128,128,0
c4: db 192,192,192,0,192,192,192,0,192,192,192,0,192,192,192,0
c5: db 255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0
unos: db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF

section .data

section .text
;void bandas_asm    (
	;unsigned char *src,
	;unsigned char *dst,
	;int filas,
	;int cols,
	;int src_row_size,
	;int dst_row_size)

bandas_asm:
;rdi = src
;rsi = dst
;ecx = filas			<--- los parámetros "filas" y "columnas"
;edx = cols			<--- llegan al revés de como dice la aridad
;r8d = src_row_size
;r9d = dst_row_size
push rbp
mov rbp, rsp
push r12
push r13
%define i r10
%define j r11
%define cols rdx
%define filas rcx
mov ecx, ecx
mov edx, edx
mov r8d, r8d
mov r9d, r9d
xor i,i
xor j,j
sal cols, 2
movdqu xmm11, [c1]		;xmm11 tiene hardcodeado el primer caso 
movdqu xmm12, [c2]		;xmm12 tiene hardcodeado el segundo caso
movdqu xmm13, [c3]		;xmm13 tiene hardcodeado el tercer caso
movdqu xmm14, [c4]		;xmm14 tiene hardcodeado el cuarto caso
movdqu xmm15, [c5]		;xmm15 tiene hardcodeado el quinto caso
.CicloFilas:
cmp i, filas
je .Fin
xor j,j
mov r12, rdi                    ;r12 se guarda el principio de la fila actual de src
mov r13, rsi                    ;r13 se guarda el principio de la fila actual de dst 
.CicloColumnas:
cmp j, cols
je .FinColumnas
add j, 16
cmp j, cols
jl .NoArreglar			;si estoy por hacer una lectura inválida,
mov rdi, r12			;esta sección mueve los punteros al final
mov rsi, r13			;de la fila y les resta 16, para procesar
add rdi, cols			;los últimos 4 píxeles de dicha fila.
add rsi, cols
sub rdi, 16
sub rsi, 16
mov j, cols
.NoArreglar:
sub j, 16
movdqu xmm0, [rdi]		;xmm0 = |b0|g0|r0|a0|b1|g1|r1|a1|b2|g2|r2|a2|b3|g3|r3|a3|
movdqu xmm1, [alpha]		;xmm1 = |0|0|0|0xff|0|0|0|0xff|0|0|0|0xff|0|0|0|0xff|
movdqu xmm3, xmm1		;xmm3 = |0|0|0|0xff|0|0|0|0xff|0|0|0|0xff|0|0|0|0xff|
pand xmm1, xmm0			;xmm1 tiene los alpha de la imagen fuente
pcmpeqd xmm4,xmm4		;xmm4 = |0xFF|0xFF|0xFF|0xFF|0xFF|0xFF|0xFF|0xFF|
;movdqu xmm4, [unos]
pxor xmm3, xmm4			;niego el registro xmm3
pand xmm0, xmm3			;xmm0 = |b0|g0|r0|00|b1|g1|r1|00|b2|g2|r2|00|b3|g3|r3|00|
movdqu xmm2, xmm0		;xmm2 = |b0|g0|r0|00|b1|g1|r1|00|b2|g2|r2|00|b3|g3|r3|00|
pxor xmm3, xmm3			;xmm3 = 0
punpcklbw xmm0, xmm3		;extiendo la precisión de la parte baja (píxeles 0 y 1)
phaddw xmm0, xmm0
phaddw xmm0, xmm0		;xmm0 = |b0+g0+r0|b1+g1+r1|*|*|*|*|*|*|
punpckhbw xmm2, xmm3		;extiendo la precisión de la parte alta (píxeles 2 y 3)
phaddw xmm2, xmm2
phaddw xmm2, xmm2		;xmm2 = |b2+g2+r2|b3+g3+r3|*|*|*|*|*|*|
pslldq xmm0, 12			;xmm0 = |0|0|0|0|0|0|b0+g0+r0|b1+g1+r1|
psrldq xmm0, 12			;xmm0 = |b0+g0+r0|b1+g1+r1|0|0|0|0|0|0|
pslldq xmm2, 12			;xmm2 = |0|0|0|0|0|0|b2+g2+r2|b3+g3+r3|
psrldq xmm2, 8			;xmm2 = |0|0|b2+g2+r2|b3+g3+r3|0|0|0|0|
por xmm0, xmm2			;xmm0 = |b0+g0+r0|b1+g1+r1|b2+g2+r2|b3+g3+r3|0|0|0|0|
punpcklwd xmm0, xmm3		;xmm0 = |b0+g0+r0|b1+g1+r1|b2+g2+r2|b3+g3+r3|
.Caso1:
movdqu xmm2, [if1]
pcmpgtd xmm2, xmm0		;xmm2 tiene una máscara que filtra los píxeles que estaban en la primer banda
.Caso2:
movdqu xmm3, xmm0
movdqu xmm4, xmm0
movdqu xmm10, [if1]
pcmpeqd xmm3, xmm10
pcmpgtd xmm4, xmm10
por xmm3, xmm4
movdqu xmm4, [if2]
pcmpgtd xmm4, xmm0
pand xmm3, xmm4			;xmm3 tiene una máscara que filtra los píxeles que estaban en la segunda banda
.Caso3:
movdqu xmm4, xmm0
movdqu xmm5, xmm0
movdqu xmm10, [if2]
pcmpeqd xmm4, xmm10
pcmpgtd xmm5, xmm10
por xmm4, xmm5
movdqu xmm5, [if3]
pcmpgtd xmm5, xmm0
pand xmm4, xmm5			;xmm4 tiene una máscara que filtra los píxeles que estaban en la tercer banda
.Caso4:
movdqu xmm5, xmm0
movdqu xmm6, xmm0
movdqu xmm10, [if3]
pcmpeqd xmm5, xmm10
pcmpgtd xmm6, xmm10
por xmm5, xmm6
movdqu xmm6, [if4]
pcmpgtd xmm6, xmm0
pand xmm5, xmm6			;xmm5 tiene una máscara que filtra los píxeles que estaban en la cuarta banda
.Caso5:
movdqu xmm6, xmm0
movdqu xmm10, [if4]
pcmpgtd xmm6, xmm10
movdqu xmm7, xmm0
pcmpeqd xmm7, xmm10
por xmm6, xmm7			;xmm6 tiene una máscara que filtra los píxeles que estaban en la quinta banda
.Aplicar:
pand xmm2, xmm11		;xmm2 tiene procesados los píxeles de la primer banda
pand xmm3, xmm12		;xmm3 tiene procesados los píxeles de la segunda banda
pand xmm4, xmm13		;xmm4 tiene procesados los píxeles de la tercer banda
pand xmm5, xmm14		;xmm5 tiene procesados los píxeles de la quinta banda
pand xmm6, xmm15		;xmm6 tiene procesados los píxeles de la sexta banda
por xmm2, xmm3
por xmm4, xmm5
por xmm2, xmm4
por xmm2, xmm6
por xmm2, xmm1			;xmm2 tiene los cuatro píxeles ya procesados
movdqu [rsi], xmm2
add j, 16
add rdi, 16
add rsi, 16
jmp .CicloColumnas
.FinColumnas:
inc i
mov rdi, r12
mov rsi, r13
add rdi, r8
add rsi, r9
jmp .CicloFilas
.Fin:
pop r13
pop r12
pop rbp
ret 
